在 Day 8 介紹 Secret 時,我們曾經提到 RBAC,因為 Secret 能不能被讀取,取決於使用者或 ServiceAccount 是否被授予對應權限。
經過 Day 20~23 的 Helm 系列後,我們已經能打包、管理與部署完整的應用程式。但還有一個很重要的問題:
叢集裡的每個人、每個 Pod,都可以隨意操作任何 Kubernetes 資源嗎?
答案當然是不行。
就像公司裡不同角色有不同權限,例如財務可以看帳、工程師可以部署、實習生可能只有讀取權限,Kubernetes 也有一套角色權限控制機制:
RBAC(Role-Based Access Control)
今天內容包含:
kubectl auth can-i 測試權限cluster-admin、admin、edit、view
以下操作皆在 master 節點執行。
先看一個常見的權限需求:
| 角色 | 應該能做的事 | 不該做的事 |
|---|---|---|
| 叢集管理員 | 管理整個叢集 | 通常具備完整管理權限 |
| 開發者 | 在自己的 Namespace 裡部署、查看 Pod / Service | 刪除其他 Namespace、修改叢集層級設定 |
| 監控系統 | 讀取 Pod、Node 等監控所需資訊 | 任意刪除或修改資源 |
| CI/CD Pipeline | 部署到指定 Namespace | 操作其他 Namespace 或取得不需要的 Secret |
如果沒有適當的權限控制,只要取得 Kubernetes API 的存取身分,就可能獲得超出實際需求的權限。
RBAC 的目的,就是依照使用者、ServiceAccount 或 Group 的角色,限制它們可以操作哪些資源、執行哪些動作。
💡 RBAC 是 Kubernetes 內建的 Authorization 機制之一
Kubernetes API Server 支援多種 Authorization Mode,例如
RBAC、Node、Webhook等。實務上 RBAC 是非常常見的權限管理方式,可以針對不同使用者與 ServiceAccount 授予最小必要權限。
關於 Authorization,我之後會另外開新系列深入說明。
RBAC 可以用一句話概括:
「誰(Subject)」透過「綁定(Binding)」獲得「角色(Role / ClusterRole)」中定義的權限(Rules)。

| 元件 | 作用 | 範圍 |
|---|---|---|
| Role | 定義某個 Namespace 內可以操作哪些資源、執行哪些動作 | 單一 Namespace |
| ClusterRole | 定義可跨 Namespace 使用,或針對 cluster-scoped resources 的權限 | 叢集層級 |
| RoleBinding | 在某個 Namespace 中,將 Role 或 ClusterRole 綁定給 Subject | 單一 Namespace |
| ClusterRoleBinding | 將 ClusterRole 綁定給 Subject,授予叢集範圍權限 | 全叢集 |
💡 簡單記法
Role/RoleBinding:主要處理 Namespace 範圍的權限ClusterRole/ClusterRoleBinding:處理叢集層級或跨 Namespace 的權限
RBAC 可以綁定三種 Subject:
| Subject 類型 | 說明 | 常見場景 |
|---|---|---|
| User | 外部身分系統驗證後的使用者 | 開發者、管理員 |
| Group | 使用者群組 | 團隊層級權限管理 |
| ServiceAccount | Kubernetes 內提供給 Pod 使用的身分 | CI/CD、監控系統、應用程式 |
⚠️ User 和 Group 不是 Kubernetes Resource
Kubernetes 不會替你建立或保存 User / Group,因此不能用
kubectl get users查詢。它們通常來自外部 Authentication 機制,例如 Client Certificate、OIDC 等;只有 ServiceAccount 是 Kubernetes 原生 Resource。
kubectl create namespace dev-team
vim dev-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev-team
name: pod-reader
rules:
- apiGroups: [""] # "" 代表 core API group
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"] # 允許查看 Pod 日誌
kubectl apply -f dev-role.yaml
💡
apiGroups怎麼填?
apiGroups用來指定資源所屬的 API Group。常見例子:
"":Core API Group,例如 Pod、Service、ConfigMap、Secret"apps":Deployment、StatefulSet、DaemonSet"batch":Job、CronJob"rbac.authorization.k8s.io":Role、ClusterRole、RoleBinding、ClusterRoleBinding如果不確定某個資源屬於哪個 API Group,可以使用:
kubectl api-resources查看各個 Kubernetes Resource 對應的 API Group。
vim cluster-monitor-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-monitor
rules:
- apiGroups: [""]
resources: ["pods", "nodes", "services"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets"]
verbs: ["get", "list", "watch"]
kubectl apply -f cluster-monitor-role.yaml
| 情境 | 選擇 | 原因 |
|---|---|---|
| 開發者只能操作自己的 Namespace | Role | 權限限定在單一 Namespace |
| 監控系統需要讀取所有 Namespace | ClusterRole | 定義跨 Namespace 的權限,通常搭配 ClusterRoleBinding |
| 操作 Node、PV 等非 Namespace 資源 | ClusterRole | 這些屬於 cluster-scoped resources |
| 定義可重用的權限模板 | ClusterRole | 可以搭配不同 Namespace 的 RoleBinding 重複使用 |
Role 或 ClusterRole 只負責定義「有哪些權限」,本身不會直接授權給任何人。
還需要透過 RoleBinding 或 ClusterRoleBinding,把這些權限綁定給 User、Group 或 ServiceAccount,權限才會真正生效。
# 建立一個代表「開發者」的 ServiceAccount
kubectl create serviceaccount dev-user -n dev-team
vim dev-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-pod-reader
namespace: dev-team
subjects:
- kind: ServiceAccount
name: dev-user
namespace: dev-team
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
kubectl apply -f dev-rolebinding.yaml
⚠️
roleRef建立後不能修改RoleBinding 或 ClusterRoleBinding 建立後,
roleRef是不可變更的。如果要改綁定到另一個 Role / ClusterRole,需要刪除原本的 Binding 再重新建立。

kubectl auth can-iKubernetes 提供了 kubectl auth can-i,可以直接測試某個身份是否具備特定權限。
# dev-user 能不能在 dev-team Namespace 讀取 Pod?
kubectl auth can-i get pods \
--namespace=dev-team \
--as=system:serviceaccount:dev-team:dev-user
# → yes
# 能不能刪除 Pod?
kubectl auth can-i delete pods \
--namespace=dev-team \
--as=system:serviceaccount:dev-team:dev-user
# → no
# 能不能讀取 default Namespace 的 Pod?
kubectl auth can-i get pods \
--namespace=default \
--as=system:serviceaccount:dev-team:dev-user
# → no
最後一個會得到 no,因為我們建立的 Role 只在 dev-team Namespace 內生效。
kubectl auth can-i --list \
--namespace=dev-team \
--as=system:serviceaccount:dev-team:dev-user
可以從結果中確認:

代表 dev-user 可以讀取 Pod 與 Pod Log,但沒有刪除 Pod 的權限。
💡
--as的格式
- ServiceAccount:
--as=system:serviceaccount:<namespace>:<name>- User:
--as=<username>- Group:搭配
--as-group=<groupname>
--as屬於身份模擬(Impersonation),目前執行指令的身份本身需要有對應的 Impersonation 權限。
ServiceAccount 很常用來讓 Pod 裡的程式以特定身份存取 Kubernetes API。
例如監控系統可能需要讀取 Pod 資訊,CI/CD 可能需要部署到指定 Namespace。
vim sa-test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: sa-test
namespace: dev-team
spec:
serviceAccountName: dev-user
containers:
- name: kubectl
image: bitnami/kubectl:latest
command: ["sleep", "3600"]
建立 Pod:
kubectl apply -f sa-test-pod.yaml
先進入 Pod:
kubectl exec -it sa-test -n dev-team -- bash
接著在 Pod 內測試:
# 可以讀取 dev-team Namespace 的 Pod
kubectl get pods -n dev-team
應該可以正常列出 Pod。
再測試其他 Namespace:
kubectl get pods -n default
會得到 Forbidden,因為 dev-user 沒有 default Namespace 的權限。
最後測試刪除 Pod:
kubectl delete pod sa-test -n dev-team
同樣會得到 Forbidden,因為我們只授予了讀取權限,沒有 delete 權限。
離開 Pod:
exit

📝 Pod 如何取得 ServiceAccount Credential?
預設情況下,Kubernetes 會把 ServiceAccount 的 Credential 掛載到 Pod:
/var/run/secrets/kubernetes.io/serviceaccount/
kubectl或 Kubernetes Client Library 可以利用這些資訊向 API Server 驗證身份。如果 Pod 不需要存取 Kubernetes API,也可以關閉自動掛載:
automountServiceAccountToken: false
Kubernetes 預設提供了幾個常用的 ClusterRole,可以直接拿來授權:
kubectl get clusterroles | grep -E "^(admin|edit|view|cluster-admin)"

| ClusterRole | 權限 | 適合誰 |
|---|---|---|
| cluster-admin | 對叢集內所有資源執行所有操作 | 叢集管理員 |
| admin | Namespace 內大多數資源的完整管理權限,包含建立 Role / RoleBinding | Namespace 管理員 |
| edit | Namespace 內大多數資源的讀寫權限,但不能管理 Role / RoleBinding | 開發者 |
| view | Namespace 內大多數資源的唯讀權限,但不能讀取 Secret | 唯讀使用者 |
kubectl create rolebinding dev-edit \
--clusterrole=edit \
--serviceaccount=dev-team:dev-user \
--namespace=dev-team
這樣 dev-user 就能在 dev-team Namespace 中使用 edit ClusterRole 所定義的權限。
💡 ClusterRole 也可以搭配 RoleBinding
這樣可以重用 ClusterRole 的權限定義,但實際授權範圍仍限制在 RoleBinding 所在的 Namespace。
🔒 Principle of Least Privilege(最小權限原則)
只授予完成任務所需要的最小權限,避免給予不必要的存取能力。
| 場景 | 建議做法 |
|---|---|
| 開發者日常操作 | 使用 edit ClusterRole + RoleBinding,把權限限制在指定 Namespace |
| CI/CD Pipeline | 建立專用 ServiceAccount 與 Role,只授予部署流程實際需要的操作 |
| 監控系統 | ClusterRole 只給需要的 get / list / watch,再搭配 ClusterRoleBinding |
| 應用程式讀取 ConfigMap | 自訂 Role,只允許讀取需要的 ConfigMap |
| 除錯 / On-call | 臨時授權,需要結束後移除 |
cluster-admin —— 除非真的需要叢集最高權限* Wildcard —— 未來新增的 Resource 也可能一起獲得權限default ServiceAccount
| 問題 | 原因與解法 |
|---|---|
Error from server (Forbidden): ... |
用 kubectl auth can-i 確認目前身份是否具備對應權限 |
| RoleBinding 建了但權限沒生效 | 檢查 namespace、subjects、roleRef 是否正確 |
想修改 RoleBinding 的 roleRef |
roleRef 建立後不能修改,需要刪除重建 |
Pod 裡的程式收到 403 Forbidden |
檢查 serviceAccountName 與對應的 RoleBinding |
今天我們學會了 Kubernetes 的核心權限控制機制 —— RBAC,了解如何控制「誰可以對哪些資源執行哪些操作」。
| 重點 | 說明 |
|---|---|
| RBAC 四個核心資源 | Role、ClusterRole、RoleBinding、ClusterRoleBinding |
| Role vs ClusterRole | Role 用於 Namespace 範圍;ClusterRole 可定義叢集層級或可重用的權限 |
| ServiceAccount | Pod 存取 Kubernetes API 時常用的身份 |
kubectl auth can-i |
用來驗證權限,也可以搭配 --as 模擬不同身份 |
| 內建 ClusterRole | cluster-admin、admin、edit、view 提供常見的權限層級 |
| 最小權限原則 | 只授予完成任務所需要的最小權限 |
學會 RBAC 之後,下一篇我們繼續深入 Kubernetes 安全性 —— NetworkPolicy(網路策略),學習如何控制 Pod 之間的網路流量與存取範圍!